/*
 * Copyright (c) 2025 CAX Conversion Project
 */
package com.comac.ins.isfd.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import com.comac.ins.common.core.domain.R;
import com.comac.ins.common.core.exception.base.BaseException;
import com.comac.ins.common.core.validate.QueryGroup;
import com.comac.ins.common.excel.core.ExcelResult;
import com.comac.ins.common.excel.utils.ExcelUtil;
import com.comac.ins.common.log.annotation.Log;
import com.comac.ins.common.log.enums.BusinessType;
import com.comac.ins.common.mybatis.core.page.PageQuery;
import com.comac.ins.common.mybatis.core.page.TableDataInfo;
import com.comac.ins.common.web.core.BaseController;
import com.comac.ins.common.core.constant.CommonConstant;
import com.comac.ins.isfd.domain.bo.IsfdAnalysisParameterConfigBo;
import com.comac.ins.isfd.domain.bo.query.IsfdAnalysisParameterConfigQueryBo;
import com.comac.ins.isfd.domain.bo.IsfdOperatorParameterConfigBo;
import com.comac.ins.isfd.domain.bo.query.IsfdOperatorParameterConfigQueryBo;
import com.comac.ins.isfd.domain.vo.*;
import com.comac.ins.isfd.listener.InportOperatorParameterConfigListener;
import com.comac.ins.isfd.service.IIsfdParameterConfigService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * 参数库controller
 *
 * @author hxloongs
 * @date 2024-7-15
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/parameter")
public class IsfdParameterConfigController extends BaseController {
    @Autowired
    private IIsfdParameterConfigService iIsfdParameterConfigService;

    @SaCheckPermission("isfd:parameter:config:analysis:build:name")
    @PostMapping(value = "/config/analysis/build/name")
    @Operation(summary = "算法参数配置冗余算法名和算子名", security = @SecurityRequirement(name = "isfd:parameter:config:analysis:build:name"))
    public R<Void> buildParameterConfigAnalysisTypeAndOperatorName() {
        return toAjax(iIsfdParameterConfigService.buildParameterConfigAnalysisTypeAndOperatorName());
    }

    @SaCheckPermission("isfd:parameter:config:list:count")
    @GetMapping("/config/list/count")
    @Operation(summary = "算法和算子参数首页统计查询接口", security = @SecurityRequirement(name = "isfd:parameter:config:list:count\""))
    public R<List<IsfdParameterConfigCountObjectVo>> listCount() {
        return R.ok(iIsfdParameterConfigService.listCount());
    }

    @SaCheckPermission("isfd:parameter:config:analysis:list")
    @PostMapping("/config/analysis/list")
    @Operation(summary = "算法参数配置分页列表接口", security = @SecurityRequirement(name = "isfd:parameter:config:analysis:list"))
    public TableDataInfo<IsfdAnalysisParameterConfigVo> getParameterConfigAnalysisPageList(@RequestBody IsfdAnalysisParameterConfigQueryBo queryBo) {
        return iIsfdParameterConfigService.getParameterConfigAnalysisPageList(queryBo);
    }

    @SaCheckPermission("isfd:parameter:config:analysis:add")
    @PostMapping(value = "/config/analysis/add")
    @Operation(summary = "算法参数配置添加", security = @SecurityRequirement(name = "isfd:parameter:config:analysis:add"))
    public R<Void> parameterConfigAnalysisAdd(@RequestBody IsfdAnalysisParameterConfigBo isfdAnalysisParameterConfigBo) {
        return toAjax(iIsfdParameterConfigService.parameterConfigAnalysisAdd(isfdAnalysisParameterConfigBo));
    }

    @SaCheckPermission("isfd:parameter:config:analysis:update")
    @PostMapping(value = "/config/analysis/update")
    @Operation(summary = "算法参数配置算法修改", security = @SecurityRequirement(name = "isfd:parameter:config:analysis:update"))
    public R<Void> parameterConfigAnalysisUpdate(@RequestBody IsfdAnalysisParameterConfigBo isfdAnalysisParameterConfigBo) {
        return toAjax(iIsfdParameterConfigService.parameterConfigAnalysisUpdate(isfdAnalysisParameterConfigBo));
    }

    @SaCheckPermission("isfd:parameter:config:analysis:remove")
    @Log(title = "算法参数配置删除", businessType = BusinessType.DELETE)
    @DeleteMapping("/config/analysis/{parameterConfigIds}")
    public R<Void> parameterConfigAnalysisRemove(@NotEmpty(message = "算法id不能为空")
                                                 @PathVariable String[] parameterConfigIds) {
        return toAjax(iIsfdParameterConfigService.parameterConfigAnalysisRemove(List.of(parameterConfigIds)));
    }

    @SaCheckPermission("isfd:parameter:config:operator:build:custom:json:field")
    @PostMapping("/config/operator/build/custom/json/field")
    @Operation(summary = "算子参数构建自定义配置字段并初始化赋值", security = @SecurityRequirement(name = "isfd:parameter:config:operator:build:custom:json:field"))
    public R<Void> buildCustomJsonField() {
        return toAjax(iIsfdParameterConfigService.buildCustomJsonField());
    }

    @SaCheckPermission("isfd:parameter:config:operator:list")
    @PostMapping("/config/operator/list")
    @Operation(summary = "算子参数配置分页查询", security = @SecurityRequirement(name = "isfd:parameter:config:operator:list"))
    public TableDataInfo<IsfdOperatorParameterConfigVo> queryPageParameterConfigOperatorList(@RequestBody IsfdOperatorParameterConfigQueryBo queryBo) {
        return iIsfdParameterConfigService.queryPageParameterConfigOperatorList(queryBo);
    }

    @SaCheckPermission("isfd:parameter:config:operator:path:tree")
    @GetMapping("/config/operator/path/tree")
    @Operation(summary = "左侧菜单算子参数配置path树结构接口", security = @SecurityRequirement(name = "isfd:parameter:config:operator:path:tree"))
    public R<IsfdOperatorParameterConfigPathTreeVo> queryPageParameterConfigOperatorPathTree() {
        return R.ok(iIsfdParameterConfigService.queryPageParameterConfigOperatorPathTree());
    }

    @SaCheckPermission("isfd:parameter:config:operator:add")
    @PostMapping(value = "/config/operator/add")
    @Operation(summary = "算子参数配置添加", security = @SecurityRequirement(name = "isfd:parameter:config:operator:add"))
    public R<Void> parameterConfigOperatorAdd(@RequestBody IsfdOperatorParameterConfigBo isfdOperatorParameterConfigBo) {
        return toAjax(iIsfdParameterConfigService.parameterConfigOperatorAdd(isfdOperatorParameterConfigBo));
    }

    @SaCheckPermission("isfd:parameter:config:operator:update")
    @PostMapping(value = "/config/operator/update")
    @Operation(summary = "算子参数配置修改", security = @SecurityRequirement(name = "isfd:parameter:config:operator:update"))
    public R<Void> parameterConfigOperatorUpdate(@RequestBody IsfdOperatorParameterConfigBo isfdOperatorParameterConfigBo) {
        return toAjax(iIsfdParameterConfigService.parameterConfigOperatorUpdate(isfdOperatorParameterConfigBo));
    }

    @SaCheckPermission("isfd:parameter:config:operator:remove")
    @Log(title = "算子参数配置删除", businessType = BusinessType.DELETE)
    @DeleteMapping("/config/operator/{operatorParameterConfigIds}")
    public R<Void> parameterConfigOperatorRemove(@NotEmpty(message = "算子参数配置id不能为空")
                                                 @PathVariable String[] operatorParameterConfigIds) {
        return toAjax(iIsfdParameterConfigService.parameterConfigOperatorRemove(List.of(operatorParameterConfigIds)));
    }

    @SaCheckPermission("isfd:parameter:config:operator:getAnalysisOperatorList")
    @GetMapping("/config/operator/getAnalysisOperatorList")
    @Operation(summary = "获取算法对应的所有算子列表", security = @SecurityRequirement(name = "isfd:parameter:config:operator:getAnalysisOperatorList"))
    public R<List<IsfdOperatorNameVo>> getAnalysisOperatorList(@NotEmpty(message = "算法id不能为空") @RequestParam("analysisRefId") String analysisRefId) {
        return R.ok(iIsfdParameterConfigService.getAnalysisOperatorList(analysisRefId));
    }


    @SaCheckPermission("isfd:parameter:config:related:operator:map")
    @GetMapping("/config/related/operator/map")
    @Operation(summary = "获取配置关联上下游参数列表接口", security = @SecurityRequirement(name = "isfd:parameter:config:related:operator:map"))
    public TableDataInfo<IsfdOperatorMapParameterVo> getConfigRelatedOperatorMap(@NotEmpty(message = "算子id不能为空") @RequestParam("operatorRefId") String operatorRefId,
                                                                                 @NotEmpty(message = "算法id不能为空") @RequestParam("analysisRefId") String analysisRefId,
                                                                                 PageQuery pageQuery) {
        return iIsfdParameterConfigService.getConfigRelatedOperatorMap(operatorRefId, analysisRefId, pageQuery);
    }


    @SaCheckPermission("isfd:parameter:config:operator:getFieldIdList")
    @GetMapping("/config/operator/getFieldIdList")
    @Operation(summary = "查询算子细的所有fieldId", security = @SecurityRequirement(name = "isfd:parameter:config:operator:getFieldIdList"))
    public R<List<IsfdOperatorParameterConfigVo>> getFieldIdList(@NotEmpty(message = "算子id不能为空") @RequestParam("operatorRefId") String operatorRefId) {
        return R.ok(iIsfdParameterConfigService.getFieldIdList(operatorRefId));
    }

    @SaCheckPermission("isfd:parameter:config:operator:template:export")
    @GetMapping("/config/operator/template/export")
    @Operation(summary = "算子参数模版导出", security = @SecurityRequirement(name = "isfd:parameter:config:operator:template:export"))
    public void exportParameterConfigOperatorTemplate(HttpServletResponse response) {
        ExcelUtil.exportTemplateWithOutData(CommonConstant.OPERATOR_PARAMETER_CONFIG_NAME, CommonConstant.OPERATOR_PARAMETER_CONFIG_FILE_PATH, response);
    }


    @SaCheckPermission("isfd:parameter:config:operator:import")
    @Log(title = "算子参数导入", businessType = BusinessType.IMPORT)
    @PostMapping(value = "/config/operator/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<Void> importParameterConfigOperator(@RequestPart("file") MultipartFile file) {
        String analysis = null;
        try {
            ExcelResult<IsfdOperatorParameterConfigImportVo> result = ExcelUtil.importExcel(file.getInputStream(), IsfdOperatorParameterConfigImportVo.class, new InportOperatorParameterConfigListener());
            analysis = result.getAnalysis();
        } catch (Exception e) {
            log.error("算子参数导入失败或者部分失败", e);
            throw new BaseException(e.getMessage());
        }
        return R.ok(analysis);
    }


    @SaCheckPermission("isfd:parameter:config:operator:export")
    @GetMapping("/config/operator/export")
    @Operation(summary = "算子参数导出", security = @SecurityRequirement(name = "isfd:parameter:config:operator:export"))
    public void exportParameterConfigOperator(@Validated(QueryGroup.class) IsfdOperatorParameterConfigQueryBo queryBo, HttpServletResponse response) {
        iIsfdParameterConfigService.exportParameterConfigOperator(queryBo, response);
    }

}
